package com.itheima.health.security;

import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.health.pojo.Permission;
import com.itheima.health.pojo.Role;
import com.itheima.health.service.UserService;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName SpringSecurityUserService
 * @Description TODO
 * @Author ly
 * @Company 深圳黑马程序员
 * @Date 2019/8/31 8:52
 * @Version V1.0
 */
@Component
public class SpringSecurityUserService implements UserDetailsService {

    @Reference
    UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("登录名："+username);
        // 使用登录名，查询当前登录名，具有的用户信息（角色集合、权限集合）
        com.itheima.health.pojo.User user = userService.findUserByUsername(username);
        // 登录名输入有误
        if(user==null){
            return null; // 表示登录名输入有误，抛出异常：org.springframework.security.authentication.InternalAuthenticationServiceException
        }
        // 获取密码（BCryptPasswordEncoder）,底层自动完成match的匹配
        String password = user.getPassword();
        // 指定当前用户具有的角色和权限
        List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
        if(user.getRoles()!=null && user.getRoles().size()>0){
            for (Role role : user.getRoles()) {
                if(role.getPermissions()!=null && role.getPermissions().size()>0){
                    for (Permission permission : role.getPermissions()) {
                        list.add(new SimpleGrantedAuthority(permission.getKeyword())); // 权限
                    }
                }
            }
        }

        /**
         * public User(String username, String password, Collection<? extends GrantedAuthority> authorities)
         * 第二个参数表示：从数据库中查询的密码
         * SpringSecurity会使用该密码和页面输入的密码进行比对，如果一致就登录成功；如果不一致，就抛出异常，指定到登录页面
         * 异常：org.springframework.security.authentication.BadCredentialsException: Bad credentials
         */
        return new User(username,password,list);
    }
}
